import axios from 'axios';
import CancelRequest from './cancelRequest';
import LoadingInstance from './loading';
import { Message } from 'element-ui';
import { errorCode } from '@/utils/index';
import errorHandle from './errorHandle';

// 实例化取消请求对象
let cancelRequest = new CancelRequest();

// 实例化loading对象
let loadingInstance = new LoadingInstance();

class HttpRequest {
  // 获取基础配置
  getInsideConfig() {
    const config = {
      timeout: 30000 //请求超时时间
    };

    return config;
  }

  // 设定拦截器
  interceptors(instance) {
    // 请求拦截器
    instance.interceptors.request.use(
      config => {
        // 开启loading
        if (!config.headers.hideLoading) {
          let loadingText = '请求中，请稍候……';
          if (config.headers.loadingText) {
            loadingText = decodeURI(config.headers.loadingText);
          }

          // 延迟加载loading
          let loadingTarget = config.headers.loadingTarget || 'body';
          const loadingId = setTimeout(() => {
            loadingInstance.showLoading(loadingText, loadingTarget);
          }, loadingInstance.loadingDelay);

          // 储存延迟加载loading
          loadingInstance.requestLoadingIdList.push({
            loadingId,
            url: config.url
          });
        }

        // 处理重复请求
        cancelRequest.removePending(config);
        if (!config.headers.allowRepeatRequest) {
          cancelRequest.addPending(config, axios.CancelToken);
        }

        // 请求携带token
        if (localStorage.getItem('token')) {
          config.headers.token = localStorage.getItem('token');
        }

        return config;
      },
      err => {
        return Promise.reject(err);
      }
    );

    // 响应拦截器
    instance.interceptors.response.use(
      res => {
        // 处理loading
        loadingInstance.clearTimeoutForLoading();
        loadingInstance.hideLoading();

        // 处理重复请求
        cancelRequest.removePending(res.config);

        if (res.status === 200) {
          let code = res.data.status;
          if (code === 200) {
            return Promise.resolve(res.data);
          } else {
            if (code === 9) {
              //失败后页面有后续操作的
              return Promise.resolve(res.data);
            } else {
              let msg = res.data.message;
              Message({
                type: 'error',
                message: errorCode(msg)
              });
              return Promise.reject(res);
            }
          }
        } else {
          return Promise.reject(res);
        }
      },
      err => {
        // 接口超时处理
        let errStr = err.toString();
        if (errStr.indexOf('timeout') > -1) {
          Message({
            type: 'error',
            message: '接口请求超时，请刷新页面重试',
            duration: 5000
          });
          loadingInstance.clearTimeoutForLoading();
        }

        // 处理loading
        loadingInstance.clearTimeoutForLoading(true);
        loadingInstance.hideLoading();

        // 处理重复请求
        err.config && cancelRequest.removePending(err.config);

        errorHandle(err);
        return Promise.reject(err);
      }
    );
  }

  // 创建实例
  request(options) {
    const instance = axios.create();
    const newOptions = Object.assign(this.getInsideConfig(), options);
    this.interceptors(instance);
    return instance(newOptions);
  }

  // get方法
  get(url, data) {
    const options = Object.assign(
      {
        method: 'get',
        url
      },
      data
    );
    return this.request(options);
  }

  // post方法
  post(url, data) {
    return this.request({
      method: 'post',
      url,
      data
    });
  }

  // put方法
  put(url, data) {
    return this.request({
      method: 'put',
      url,
      data
    });
  }

  // delete方法
  delete(url, data) {
    return this.request({
      method: 'delete',
      url,
      data
    });
  }
}

export default new HttpRequest();
